
/*!
 * \file      action.cpp
 * \brief     Action implementation.
 * \author    Duriez Franck
 * \version   0.10
 */

template < class T >
Action<T>::Action(void(T::*startingprocess)(), void(T::*process)(),
                  void(T::*stoppingprocess)(),
                  T *parent, bool constant) : /*{{{*/
		m_on_start(false),
		m_on_process(false),
		m_on_stop(false),
		m_const(constant),
		m_startingprocess(startingprocess),
		m_process(process),
		m_stoppingprocess(stoppingprocess),
		m_parent(parent)
{
} /*}}}*/

template < class T >
Action<T>::Action(Action<T>& action) /*{{{*/
{
	if (m_const) /*{{{*/
	{
		throw ActionException::ModifyingConstAction("Try to copy an Action in a const Action");
	} /*}}}*/
	else /*{{{*/
	{
		stop(true); // stop the current Action and set the state bools to false
		m_startingprocess = action.m_startingprocess;
		m_process         = action.m_process;
		m_stoppingprocess = action.m_stoppingprocess;
		m_parent          = action.m_parent;
	} /*}}}*/
} /*}}}*/

template < class T >
void Action<T>::start() /*{{{*/
{
	if (m_on_process)
	{
		// only if already in process :
		// put the parent in final state and begin a new cycle
		(m_parent->*m_stoppingprocess)();
	}
	m_on_start   = true;
	m_on_process = true;
	m_on_stop    = false;
} /*}}}*/

template < class T >
bool Action<T>::isProcessing() const /*{{{*/
{
	return m_on_process;
} /*}}}*/

template < class T >
void Action<T>::stop(bool useStoppingProcess) /*{{{*/
{
	if (useStoppingProcess) (m_parent->*m_stoppingprocess)();
	m_on_start   = false;
	m_on_process = false;
	m_on_stop    = false;
} /*}}}*/

template < class T >
void Action<T>::restart(bool useStoppingProcess) /*{{{*/
{
	if (m_on_process) stop(useStoppingProcess);

	start();
} /*}}}*/

template < class T >
void Action<T>::update() /*{{{*/
{
	// continue only if on process
	if (!m_on_process) return;

	// m_on_process recalculation [1]
	m_on_process = false;

	// m_on_stop recalculation    [2]
	m_on_stop = true;

	if (m_on_start) /*{{{*/
	{   // what to do at the begin of the action
		(m_parent->*m_startingprocess)();

		// after the first step, it's not the beginning
		m_on_start = false;
	} /*}}}*/

	// processing
	(m_parent->*m_process)();

	if (m_on_stop) /*{{{*/
	{   // what to do at the end of the action
		(m_parent->*m_stoppingprocess)();

		// after the last step, it's finished
		ASSERT(!m_on_process,"","it's the end and process is not off !");
		m_on_stop = false;
	} /*}}}*/
} /*}}}*/

template < class T >
void Action<T>::maintain() /*{{{*/
{
	m_on_process = true; // [1]
	m_on_stop = false;   // [2]
} /*}}}*/

template < class T >
std::string Action<T>::toString() const /*{{{*/
{
	std::ostringstream res;
	res << "<start> " << m_on_start << " </start>" << std::endl;
	res << "<process> " << m_on_process << " </process>" << std::endl;
	res << "<stop> " << m_on_stop << " </stop>";
	return res.str();
} /*}}}*/

